﻿using Aribaccio;
using BDPAutodetect.Mgrcore;
using BDPAutodetect.Models;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;

namespace BDPAutodetect.Client
{
    public partial class ParameterViewModel : BaseViewModel<UserControl>
    {
        /// <summary>
        /// 用户管理实例
        /// </summary>
        protected UserManager UserMgr { get; set; }
        /// <summary>
        /// 参数管理实例
        /// </summary>
        protected ParameterManager ParameterMgr { get; set; }
        /// <summary>
        /// 查询当前从机设备
        /// </summary>
        [ObservableProperty]
        protected MSlave? slaveItem;
        /// <summary>
        /// 查询从机设备集
        /// </summary>
        [ObservableProperty]
        protected ObservableCollection<MSlave> slaveItems;
        /// <summary>
        /// 当前选择参数配置数据
        /// </summary>
        [ObservableProperty]
        protected MParameterData? parameter;
        /// <summary>
        /// 参数配置数据集
        /// </summary>
        [ObservableProperty]
        protected ObservableCollection<MParameterData> parameters;
        /// <summary>
        /// 参数名称集合
        /// </summary>
        public List<string> ParameterNames => this.Parameters.Count > 0 ? this.Parameters.Select(p => p.Name).ToList() : new List<string>();

        /// <summary>
        /// 构造函数[注入]
        /// </summary>
        public ParameterViewModel(UserManager argUserManager, ParameterManager argParameterManager) : base()
        {
            this.UserMgr = argUserManager;
            this.ParameterMgr = argParameterManager;
            this.SlaveItems = new ObservableCollection<MSlave>();
            this.Parameters = new ObservableCollection<MParameterData>();
        }

        /// <summary>
        /// 初始化加载权限编辑
        /// </summary>
        /// <returns></returns>
        protected async Task InitLoadPermission()
        {
            if (this.PowerPermission == null) return;
            var resultTaskPowers = this.UserMgr.GetUserPowers(this.PowerPermission.Power.ID);
            await resultTaskPowers.ConfigureAwait(false);
            if (resultTaskPowers != null && resultTaskPowers.Result != null && resultTaskPowers.Result.Count > 0)
            {
                this.IsVisibilityPermission = Visibility.Visible;
            }
        }

        /// <summary>
        /// 初始化加载查询选项数据集
        /// </summary>
        /// <returns></returns>
        protected async Task InitLoadItems()
        {
            await Task.Factory.StartNew(() =>
            {
                //初始化从机设备数据
                var slaves = this.ParameterMgr.GetSlaves();
                foreach (var item in slaves.OrderBy(v => v.ID))
                {
                    if (item.ID <= 0) continue;
                    this.SlaveItems.Add(item);
                }
                this.SlaveItem = this.SlaveItems.First();
            }, new CancellationTokenSource().Token, TaskCreationOptions.None, base.syncContextTask);
        }

        /// <summary>
        /// 设置默认
        /// </summary>
        protected void SetDefault()
        {
            if (this.Parameters.Count <= 0) return;
            //检测是否有已勾选的
            foreach (var item in this.Parameters)
            {
                if (item.IsChecked)
                {
                    this.Parameter = item;
                    return;
                }
            }
            //默认设置第一个
            this.Parameters[0].IsChecked = true;
            this.Parameter = this.Parameters[0];
        }

        /// <summary>
        /// 页面初始化加载事件
        /// </summary>
        [RelayCommand]
        public async Task ExecuteLoaded()
        {
            if (this.IsLoaded) return;
            //获取编辑权限
            var resultTask = this.InitLoadPermission();
            await resultTask.ConfigureAwait(false);

            //获取查询选项数据集
            resultTask = this.InitLoadItems();
            await resultTask.ConfigureAwait(false);

            //标记初始化加载完成
            this.IsLoaded = true;
            //初始化查询数据
            resultTask = this.ExecuteQuery();
            await resultTask.ConfigureAwait(false);
        }

        /// <summary>
        /// 树形菜单栏切换改变事件
        /// </summary>
        [RelayCommand]
        public async Task ExecuteMenuChanged(MParameterData? argParameterData)
        {
            if (argParameterData == null) return;
            if (this.Parameters == null || this.Parameters.Count() <= 0) return;
            //设置非空闲忙碌中
            this.IsExecutedIdle = false;
            var result= this.UpdateData(argParameterData);
            await result.ConfigureAwait(false);
            this.IsExecutedIdle = true;
        }

        /// <summary>
        /// 
        /// </summary>
        [RelayCommand]
        public async Task ExecuteDelete()
        {
            if (this.Parameter == null) return;
            try
            {
                this.IsExecutedIdle = false;
                var result = this.ParameterMgr.DeleteParam(this.Parameter);
                await result.ConfigureAwait(false);
                if (result != null && result.Result)
                {
                    await Task.Factory.StartNew(() =>
                    {
                        this.Parameters.Remove(this.Parameter);
                        this.SetDefault();
                    }, new CancellationTokenSource().Token, TaskCreationOptions.None, syncContextTask);
                }
            }
            finally
            {
                this.IsExecutedIdle = true;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        [RelayCommand]
        public async Task ExecuteInsert()
        {
            if (this.Parameter == null || this.SlaveItem == null) return;
            try
            {
                this.IsExecutedIdle = false;
                InputNameDialog dialog = new InputNameDialog(string.Empty, this.ParameterNames);
                bool? bResult = dialog.ShowDialog();
                if (!bResult.HasValue || !bResult.Value) return;
                if (string.IsNullOrWhiteSpace(dialog.DialogResultData)) return;

                var result = this.ParameterMgr.InsertParam(new MParameterData(0, dialog.DialogResultData, this.SlaveItem));
                await result.ConfigureAwait(false);
                if (result != null && result.Result != null)
                {
                    await this.UpdateData(result.Result);
                }
            }
            finally
            {
                this.IsExecutedIdle = true;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        [RelayCommand]
        public async Task ExecuteUpdate()
        {
            if (this.Parameter == null || this.SlaveItem == null) return;
            try
            {
                this.IsExecutedIdle = false;
                InputNameDialog dialog = new InputNameDialog(this.Parameter.Name, this.ParameterNames);
                bool? bResult = dialog.ShowDialog();
                if (!bResult.HasValue || !bResult.Value) return;
                if (string.IsNullOrWhiteSpace(dialog.DialogResultData)) return;

                var result = this.ParameterMgr.UpdateParam(new MParameterData(this.Parameter.ID, dialog.DialogResultData, this.SlaveItem));
                await result.ConfigureAwait(false);
                if (result != null && result.Result)
                {
                    this.Parameter.Name = dialog.DialogResultData;
                }
            }
            finally
            {
                this.IsExecutedIdle = true;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        [RelayCommand]
        public async Task ExecuteClone()
        {
            if (this.Parameter == null) return;
            try
            {
                this.IsExecutedIdle = false;
                InputNameDialog dialog = new InputNameDialog(this.Parameter.Name, this.ParameterNames);
                bool? bResult = dialog.ShowDialog();
                if (!bResult.HasValue || !bResult.Value) return;
                if (string.IsNullOrWhiteSpace(dialog.DialogResultData)) return;

                //克隆数据，并清除ID
                var cloneParameter = this.Parameter.CloneDeep();
                cloneParameter.ID = 0;
                cloneParameter.Name = dialog.DialogResultData.Trim();
                foreach (var item in cloneParameter.Limits)
                {
                    item.ID = 0;
                }

                var result = this.ParameterMgr.InsertParam(cloneParameter);
                await result.ConfigureAwait(false);
                if (result != null && result.Result != null)
                {
                    await this.UpdateData(result.Result);
                }
            }
            finally
            {
                this.IsExecutedIdle = true;
            }
        }

        /// <summary>
        /// 编辑事件
        /// </summary>
        [RelayCommand]
        public async Task ExecuteParamLimitEditor(MParameterLimitData argParamLimit)
        {
            string strTitleName = this.Parameter?.Name ?? string.Empty;
            ParameterLimitEditorDialog paramLimitDialog = new ParameterLimitEditorDialog(strTitleName, argParamLimit.CloneDeep());
            bool? bResult = paramLimitDialog.ShowDialog();
            if (!bResult.HasValue || !bResult.Value) return;
            if (paramLimitDialog.DialogResultData == null) return;

            //更新数据库
            var result = this.ParameterMgr.UpdateParamLimit(paramLimitDialog.DialogResultData);
            await result.ConfigureAwait(false);
        }

        /// <summary>
        /// 查询事件
        /// </summary>
        /// <returns></returns>
        [RelayCommand]
        public async Task ExecuteQuery()
        {
            if (!this.IsExecutedIdle || this.SlaveItem == null) return;
            //设置非空闲忙碌中
            this.IsExecutedIdle = false;
            var resultTask = this.QueryData(this.SlaveItem);
            await resultTask.ConfigureAwait(false);
        }

        /// <summary>
        /// 查询s数据
        /// </summary>
        public async Task QueryData(MSlave argSlave)
        {
            await Task.Factory.StartNew(() =>
            {
                try
                {
                    this.Parameter = null;
                    this.Parameters.Clear();
                    var resultDatas = this.ParameterMgr.GetParameters(argSlave);
                    if (resultDatas != null)
                    {
                        var orderDatas = resultDatas.OrderBy(v => v.ID);
                        foreach (var item in orderDatas)
                        {
                            this.Parameters.Add(item);
                        }
                        this.SetDefault();
                    }
                }
                finally
                {
                    this.IsExecutedIdle = true;
                }
            }, new CancellationTokenSource().Token, TaskCreationOptions.None, base.syncContextTask);
        }

        /// <summary>
        /// 更新数据及状态
        /// </summary>
        /// <returns></returns>
        protected async Task UpdateData(MParameterData argParameterData)
        {
            await Task.Factory.StartNew(() =>
            {
                bool bExists = false;
                //设置界面选择项，并绑定到界面
                foreach (var ParamItem in this.Parameters)
                {
                    if (ParamItem.Equals(argParameterData))
                    {
                        bExists = true;
                        ParamItem.IsChecked = true;
                    }
                    else
                    {
                        ParamItem.IsChecked = false;
                    }
                }
                if (!bExists)
                {
                    argParameterData.IsChecked = true;
                    this.Parameters.Add(argParameterData);                  
                }
                this.Parameter = argParameterData;
            }, new CancellationTokenSource().Token, TaskCreationOptions.None, syncContextTask);

        }
    }
}
